package com.yuda.tools.miscellaneous.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.yuda.common.core.web.controller.BaseController;
import com.yuda.tools.miscellaneous.dto.AmountJson;
import com.yuda.tools.miscellaneous.dto.PaperCount;
import com.yuda.tools.miscellaneous.dto.PaperMachined;
import com.yuda.tools.miscellaneous.service.PaperCountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 此乃试卷印量表导出功能
 */
@RequestMapping("/paperCount")
@RestController
public class PaperCountController extends BaseController {


    @Autowired
    private PaperCountService paperCountService;

    @RequestMapping("/export/{examUuid}")
    public void export(@PathVariable("examUuid") String examUuid, HttpServletResponse response) throws IOException {
        String tableSubstring = examUuid.substring(9, 15);
        //根据examUuid获取后缀

        List<PaperCount> paperCounts = paperCountService.listPaperCount(examUuid, tableSubstring);
//        ExcelUtil<PaperCount> util = new ExcelUtil<>(PaperCount.class);
//        util.exportExcel(response, paperCounts, "paperCount");
        //寻找excel_student表中有的，但是没有申请的
        List<PaperMachined> list = paperCountService.manufactured(examUuid);
        ArrayList<PaperCount> needMachined = new ArrayList<>();
        for (PaperMachined paperMachined : list) {
            PaperCount paperCount = new PaperCount();
            paperCount.setSchoolId(paperMachined.getSchoolId());
            paperCount.setType(paperMachined.getType());
            paperCount.setPaperType(paperMachined.getPaperType());
            paperCount.setProvinceName(paperMachined.getProvinceName());
            paperCount.setName(paperMachined.getName());
            List<AmountJson> amountJsons = JSON.parseArray(paperMachined.getAmountJson(), AmountJson.class);
            double xsArt = 0;
            double xxArt = 0;
            double xsPhsic = 0;
            double xxPhsic = 0;
            for (AmountJson amountJson : amountJsons) {
                Integer examType = amountJson.getExamType();
                Integer onlineOffline = amountJson.getOnlineOffline();
                String strAmount = String.valueOf(amountJson.getAmount());

                if (onlineOffline == 1 && examType == 1) {
                    paperCount.setXsArt(strAmount);
                    xsArt += Double.parseDouble(strAmount);
                }
                if (onlineOffline == 1 && examType == 2) {
                    paperCount.setXsPhsic(strAmount);
                    xsPhsic += Double.parseDouble(strAmount);
                }
                if (onlineOffline == 2 && examType == 1) {
                    paperCount.setXxArt(strAmount);
                    xxArt += Double.parseDouble(strAmount);
                }
                if (onlineOffline == 2 && examType == 2) {
                    paperCount.setXxPhsic(strAmount);
                    xxPhsic += Double.parseDouble(strAmount);
                }

                if (onlineOffline == 1 && examType == 3) { //线上改革
                    paperCount.setXsPhsic(strAmount);
                    xsPhsic += Double.parseDouble(strAmount);
                }
                if (onlineOffline == 2 && examType == 3) { //线下改革
                    paperCount.setXxPhsic(strAmount);
                    xxPhsic += Double.parseDouble(strAmount);
                }
                paperCount.setXsYw(String.valueOf(xsArt + xsPhsic));
                paperCount.setXxYw(String.valueOf(xxArt + xxPhsic));

                paperCount.setXsYy(String.valueOf(xsArt + xsPhsic));
                paperCount.setXxYy(String.valueOf(xxArt + xxPhsic));

            }
            needMachined.add(paperCount);
        }

        paperCounts.addAll(needMachined);

        for (PaperCount paperCount : paperCounts) {
            //paperCount 是excel_student中的实际值
            String schoolId = paperCount.getSchoolId();//获取schoolId
            String amountJson = paperCountService.getAmountJson(examUuid, schoolId);
            if (StringUtils.isEmpty(amountJson)) {
                continue;
            }
            List<AmountJson> amountJsons = JSON.parseArray(amountJson, AmountJson.class);
            for (AmountJson json : amountJsons) { //每个学校的取出的json
                Integer examType = json.getExamType(); //1 是文科 2 是理科
                Integer onlineOffline = json.getOnlineOffline(); //1 是线上 2 是线下
                Integer amount = json.getAmount(); //表中的条数
                if (paperCount.getType() == 0) { //原生的不需要跳过
                    if ((!StringUtils.isEmpty(paperCount.getXxArt()) && Double.parseDouble(paperCount.getXxArt()) >= amount && onlineOffline == 2 && (examType == 1 || examType == 3)) ||
                            (!StringUtils.isEmpty(paperCount.getXsArt()) && Double.parseDouble(paperCount.getXsArt()) >= amount && onlineOffline == 1 && (examType == 1 || examType == 3)) ||
                            (!StringUtils.isEmpty(paperCount.getXxPhsic()) && Double.parseDouble(paperCount.getXxPhsic()) >= amount && onlineOffline == 2 && (examType == 2 || examType == 3)) ||
                            (!StringUtils.isEmpty(paperCount.getXsPhsic()) && Double.parseDouble(paperCount.getXsPhsic()) >= amount && onlineOffline == 1 && (examType == 2 || examType == 3))) {
                        continue;
                    }
                }
                //给文理科赋值 并且//重新计算小科目（非改革）
                fill4AP(paperCount, examType, onlineOffline, amount, paperCount.getType()); //如果type = 1 则无论如何都会执行重新赋值，即使 amount 和 max 一致
                fillGg(paperCount, examType, onlineOffline, amount, paperCount.getType());
            }
        }

        ExcelWriter writer = ExcelUtil.getWriter(true);

        setHeaders(writer);
        writer.setOnlyAlias(true);
        writer.write(paperCounts, true);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=pc.xlsx");
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    private void fillGg(PaperCount paperCount, Integer examType, Integer onlineOffline, Integer amount, int type) {
        if (examType == 3 && onlineOffline == 1) { //处理改革
            String xsPhsic = paperCount.getXsPhsic();
            if (StringUtils.isEmpty(xsPhsic)) return;
            double max = Math.max(Double.parseDouble(xsPhsic), amount) * 1.0;
            if ((!String.valueOf(max).equals(String.valueOf(amount))) || type == 1) {

                String maxStr = String.valueOf(max);
                String maxNumStr = String.valueOf(Math.ceil(max / 30));
                //语数英
                paperCount.setXsYw(maxStr);
                paperCount.setXsYwnum(maxNumStr);
                paperCount.setXsYy(maxStr);
                paperCount.setXsYynum(maxNumStr);

                //给物理化学生物赋值  直接赋值
                paperCount.setXsLs(maxStr);
                paperCount.setXsLsnum(maxNumStr);
                paperCount.setXsWl(maxStr);
                paperCount.setXsWlnum(maxNumStr);
                paperCount.setXsHx(maxStr);
                paperCount.setXsHxnum(maxNumStr);
                paperCount.setXsSw(maxStr);
                paperCount.setXsSwnum(maxNumStr);

                paperCount.setXsZz(maxStr);
                paperCount.setXsZznum(maxNumStr);
                paperCount.setXsLss(maxStr);
                paperCount.setXsLssnum(maxNumStr);
                paperCount.setXsDl(maxStr);
                paperCount.setXsDlnum(maxNumStr);
            }
        }

        if (examType == 3 && onlineOffline == 2) { //处理改革
            String xxPhsic = paperCount.getXxPhsic();
            if (StringUtils.isEmpty(xxPhsic)) return;
            double max = Math.max(Double.parseDouble(xxPhsic), amount) * 1.0;
            if ((!String.valueOf(max).equals(String.valueOf(amount))) || type == 1) {
                String maxStr = String.valueOf(max);
                String maxNumStr = String.valueOf(Math.ceil(max / 50));
                //语数英
                paperCount.setXxYw(maxStr);
                paperCount.setXxYwnum(maxNumStr);
                paperCount.setXxYy(maxStr);
                paperCount.setXxYynum(maxNumStr);

                //给物理化学生物赋值  直接赋值
                paperCount.setXxLs(maxStr);
                paperCount.setXxLsnum(maxNumStr);
                paperCount.setXxWl(maxStr);
                paperCount.setXxWlnum(maxNumStr);
                paperCount.setXxHx(maxStr);
                paperCount.setXxHxnum(maxNumStr);
                paperCount.setXxSw(maxStr);
                paperCount.setXxSwnum(maxNumStr);

                paperCount.setXxZz(maxStr);
                paperCount.setXxZznum(maxNumStr);
                paperCount.setXxLlss(maxStr);
                paperCount.setXxLssnum(maxNumStr);
                paperCount.setXxDl(maxStr);
                paperCount.setXxDlnum(maxNumStr);
            }
        }
    }

    private void fill4AP(PaperCount paperCount, Integer examType, Integer onlineOffline, Integer amount, int type) {
        if (onlineOffline == 1 && examType == 2) { //线上并且理科
            String xsPhsic = paperCount.getXsPhsic(); // excelStudent表的线上理科
            if (StringUtils.isEmpty(xsPhsic)) return;
            double max = Math.max(Double.parseDouble(xsPhsic), amount) * 1.0;
            paperCount.setXsPhsic(String.valueOf(max)); //把最大的赋值给 原表
            if ((!String.valueOf(max).equals(xsPhsic)) || type == 1) { //执行重新赋值
                //给线上语文英语赋值
                paperCount.setXsYw(String.valueOf(Double.parseDouble(paperCount.getXsYw()) - Double.parseDouble(xsPhsic) + max));
                paperCount.setXsYwnum(String.valueOf(Math.ceil(Double.parseDouble(paperCount.getXsYw()) * 1.0 / 30)));
                paperCount.setXsYy(String.valueOf(Double.parseDouble(paperCount.getXsYy()) - Double.parseDouble(xsPhsic) + max));
                paperCount.setXsYynum(String.valueOf(Math.ceil(Double.parseDouble(paperCount.getXsYy()) * 1.0 / 30)));

                //给物理化学生物赋值  直接赋值
                paperCount.setXsLs(String.valueOf(max));
                String s = String.valueOf(Math.ceil(max / 30));
                paperCount.setXsLsnum(s);

                paperCount.setXsWl(String.valueOf(max));
                paperCount.setXsWlnum(s);
                paperCount.setXsHx(String.valueOf(max));
                paperCount.setXsHxnum(s);
                paperCount.setXsSw(String.valueOf(max));
                paperCount.setXsSwnum(s);

            }
        }

        if (onlineOffline == 1 && examType == 1) { //线上并且文科
            String xsArt = paperCount.getXsArt(); // excelStudent表的线上并且文科
            if (StringUtils.isEmpty(xsArt)) return;
            double max = Math.max(Double.parseDouble(xsArt), amount) * 1.0;
            paperCount.setXsArt(String.valueOf(max)); //把最大的赋值给 原表
            if ((!String.valueOf(max).equals(xsArt)) || type == 1) { //执行重新赋值
                //给线上语文英语赋值
                paperCount.setXsYw(String.valueOf(Double.parseDouble(paperCount.getXsYw()) - Double.parseDouble(xsArt) + max));
                paperCount.setXsYwnum(String.valueOf(Math.ceil(Double.parseDouble(paperCount.getXsYw()) * 1.0 / 30)));
                paperCount.setXsYy(String.valueOf(Double.parseDouble(paperCount.getXsYy()) - Double.parseDouble(xsArt) + max));
                paperCount.setXsYynum(String.valueOf(Math.ceil(Double.parseDouble(paperCount.getXsYy()) * 1.0 / 30)));

                //给物理化学生物赋值  直接赋值
                paperCount.setXsWs(String.valueOf(max));
                String xsZznum = String.valueOf(Math.ceil(max / 30));
                paperCount.setXsWsnum(xsZznum);
                paperCount.setXsZz(String.valueOf(max));
                paperCount.setXsZznum(xsZznum);
                paperCount.setXsLss(String.valueOf(max));
                paperCount.setXsLssnum(xsZznum);
                paperCount.setXsDl(String.valueOf(max));
                paperCount.setXsDlnum(xsZznum);
            }
        }

        if (onlineOffline == 2 && examType == 1) { //线下并且文科
            String xxArt = paperCount.getXxArt(); // excelStudent表的线下并且文科
            if (StringUtils.isEmpty(xxArt)) return;
            double max = Math.max(Double.parseDouble(xxArt), amount) * 1.0;
            paperCount.setXxArt(String.valueOf(max)); //把最大的赋值给 原表
            if ((!String.valueOf(max).equals(xxArt)) || type == 1) { //执行重新赋值
                //给线上语文英语赋值
                paperCount.setXxYw(String.valueOf(Double.parseDouble(paperCount.getXxYw()) - Double.parseDouble(xxArt) + max));
                paperCount.setXxYwnum(String.valueOf(Math.ceil(Double.parseDouble(paperCount.getXxYw()) * 1.0 / 50)));
                paperCount.setXxYy(String.valueOf(Double.parseDouble(paperCount.getXxYy()) - Double.parseDouble(xxArt) + max));
                paperCount.setXxYynum(String.valueOf(Math.ceil(Double.parseDouble(paperCount.getXxYy()) * 1.0 / 50)));

                //给物理化学生物赋值  直接赋值
                paperCount.setXxWs(String.valueOf(max));
                String s = String.valueOf(Math.ceil(max / 50));
                paperCount.setXxWsnum(s);
                paperCount.setXxZz(String.valueOf(max));
                paperCount.setXxZznum(s);
                paperCount.setXxLlss(String.valueOf(max));
                paperCount.setXxLssnum(s);
                paperCount.setXxDl(String.valueOf(max));
                paperCount.setXxDlnum(s);

            }
        }

        if (onlineOffline == 2 && examType == 2) { //线下并且理科
            String xxPhsic = paperCount.getXxPhsic(); // excelStudent表的线下并且理科
            if (StringUtils.isEmpty(xxPhsic)) return;
            double max = Math.max(Double.parseDouble(xxPhsic), amount) * 1.0;
            paperCount.setXxPhsic(String.valueOf(max)); //把最大的赋值给 原表

            if ((!String.valueOf(max).equals(xxPhsic)) || type == 1) { //执行重新赋值
                //给线上语文英语赋值
                paperCount.setXxYw(String.valueOf(Double.parseDouble(paperCount.getXxYw()) - Double.parseDouble(xxPhsic) + max));
                paperCount.setXxYwnum(String.valueOf(Math.ceil(Double.parseDouble(paperCount.getXxYw()) * 1.0 / 50)));
                paperCount.setXxYy(String.valueOf(Double.parseDouble(paperCount.getXxYy()) - Double.parseDouble(xxPhsic) + max));
                paperCount.setXxYynum(String.valueOf(Math.ceil(Double.parseDouble(paperCount.getXxYy()) * 1.0 / 50)));

                //给物理化学生物赋值  直接赋值
                paperCount.setXxLs(String.valueOf(max));
                String s = String.valueOf(Math.ceil(max / 50));
                paperCount.setXxLsnum(s);
                paperCount.setXxWl(String.valueOf(max));
                paperCount.setXxWlnum(s);
                paperCount.setXxHx(String.valueOf(max));
                paperCount.setXxHxnum(s);
                paperCount.setXxSw(String.valueOf(max));
                paperCount.setXxSwnum(s);
            }
        }


    }

    private void setHeaders(ExcelWriter writer) {
        writer.addHeaderAlias("provinceName", "省份");
        writer.addHeaderAlias("paperType", "试卷类型");
        writer.addHeaderAlias("name", "考点名称");
        writer.addHeaderAlias("xsArt", "线上文");
        writer.addHeaderAlias("xsPhsic", "线上理");
        writer.addHeaderAlias("xxArt", "线下文");
        writer.addHeaderAlias("xxPhsic", "线下理");
        writer.addHeaderAlias("xsYw", "线上语文");
        writer.addHeaderAlias("xsYwnum", "语文线上袋数");
        writer.addHeaderAlias("xxYw", "线下语文");
        writer.addHeaderAlias("xxYwnum", "语文线下袋数");
        writer.addHeaderAlias("xsLs", "线上理数");
        writer.addHeaderAlias("xsLsnum", "理数线上袋数");
        writer.addHeaderAlias("xxLs", "线下理数");
        writer.addHeaderAlias("xxLsnum", "理数线下袋数");
        writer.addHeaderAlias("xsWs", "线上文数");
        writer.addHeaderAlias("xsWsnum", "文数线上袋数");
        writer.addHeaderAlias("xxWs", "线下文数");
        writer.addHeaderAlias("xxWsnum", "文数线下袋数");
        writer.addHeaderAlias("xsYy", "线上英语");
        writer.addHeaderAlias("xsYynum", "英语线上袋数");
        writer.addHeaderAlias("xxYy", "线下英语");
        writer.addHeaderAlias("xxYynum", "英语线下袋数");
        writer.addHeaderAlias("xsWl", "线上物理");
        writer.addHeaderAlias("xsWlnum", "物理线上袋数");
        writer.addHeaderAlias("xxWl", "线下物理");
        writer.addHeaderAlias("xxWlnum", "物理线下袋数");
        writer.addHeaderAlias("xsHx", "线上化学");
        writer.addHeaderAlias("xsHxnum", "化学线上袋数");
        writer.addHeaderAlias("xxHx", "线下化学");
        writer.addHeaderAlias("xxHxnum", "化学线下袋数");
        writer.addHeaderAlias("xsSw", "线上生物");
        writer.addHeaderAlias("xsSwnum", "生物线上袋数");
        writer.addHeaderAlias("xxSw", "线下生物");
        writer.addHeaderAlias("xxSwnum", "生物线下袋数");
        writer.addHeaderAlias("xsZz", "线上政治");
        writer.addHeaderAlias("xsZznum", "政治线上袋数");
        writer.addHeaderAlias("xxZz", "线下政治");
        writer.addHeaderAlias("xxZznum", "政治线下袋数");
        writer.addHeaderAlias("xsLss", "线上历史");
        writer.addHeaderAlias("xsLssnum", "历史线上袋数");
        writer.addHeaderAlias("xxLlss", "线下历史");
        writer.addHeaderAlias("xxLssnum", "历史线下袋数");
        writer.addHeaderAlias("xsDl", "线上地理");
        writer.addHeaderAlias("xsDlnum", "地理线上袋数");
        writer.addHeaderAlias("xxDl", "线下地理");
        writer.addHeaderAlias("xxDlnum", "地理线下袋数");
    }


}
